'''
Created on 15/05/2013

@author: Danilo M. Gomes
@see: http://glowingpython.blogspot.com.br/2011/10/perceptron.html
@see: https://gist.github.com/bhumphreys/1009664
@see: http://linguagensdeprogramacao.wordpress.com/2011/09/03/perceptron-usando-python/
'''
import random

class Perceptron:
    '''
    Inicializando os pesos, dentro do construtor.
    Definindo a taxa de aprendizagem como 0,05
    '''
    def __init__(self):
        self.peso0 = random.uniform(0,1)
        self.peso1 = random.uniform(0,1)
        self.taxa_aprendizado = 0.1
        self.aprendeu = False
        
    def saida(self, dado):
        '''
        Produz a multiplicacao entre o dado e o peso
        '''
        y = dado[0]*self.peso0+dado[1]*self.peso1 
        if y > 0:
            return 1
        else:
            return 0
    '''
    Este metodo recebe um array contendo altura(dado[0]) e peso[1]
    Modificador eh um inteiro 1 ou -1.
    Quando modificador == -1, entao o metodo atualizaPesos ira decrementar os pesos.
    '''
    def atualizaPesos(self, dado, modificador):
        self.peso0 += self.taxa_aprendizado*modificador*dado[0] #Atualiza peso da altura
        self.peso1 += self.taxa_aprendizado*modificador*dado[1] #atualiza peso do peso
    
    def treinar(self, conjunto):
        iteracao = 1
        qtd_interacoes = 10000
        while self.aprendeu != True:
            taxa_erro = 0.0
            
            for x in conjunto:
                
                resposta = self.saida(x)
                if resposta != x[-1]:
                    taxa_erro+=1
                    '''
                    Se resposta esperada for 1 e for dada 0, deve-se incrementar,
                    logo, faremos 1-0 = 1 (incrementa)
                    
                    Caso esperada 0 e dada 1, faremos
                    0-1 = -1 (decremento)
                    '''
                    modificador = x[-1] - resposta 
                    self.atualizaPesos(x, modificador)
                    print "(%)", (taxa_erro*100)/iteracao
                    
                iteracao+=1

                if iteracao >qtd_interacoes:
                    print "Total de iteracoes", iteracao -1
                    print "Taxa de Erro: %0.3f prct" %((taxa_erro*100)/iteracao)
                    self.aprendeu = True
                    
                